/************************************************************************
This file is part of lpc2xxx package for the simpleRTJ virtual machine.

This file is covered by the GNU GPL with the following exception:
  As a special exception, the copyright holders of this library give you permission
  to link this library with independent modules to produce an executable, regardless
  of the license terms of these independent modules, and to copy and distribute the
  resulting executable under terms of your choice, provided that you also meet, for
  each linked independent module, the terms and conditions of the license of that
  module. An independent module is a module which is not derived from or based on
  this library. If you modify this library, you may extend this exception to your
  version of the library, but you are not obligated to do so. If you do not wish
  to do so, delete this exception statement from your version.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL RTJ COMPUTING BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Copyright (c) 2000-2006 RTJ Computing Pty. Ltd. All rights reserved.
***********************************************************************/
package lpc2xxx.hw;


/**
 * Class providing access to console input/output functions on the LPC21xx.<br>
 * Add your own code to implement additional features if required.
 */
public class Console
{
    private static String lineSep = System.getProperty("line.separator", "\r\n");

    /** Carriage Return character */
    public static final char CR = '\r';
    /** Line Feed character */
    public static final char LF = '\n';
    /** Back Space character */
    public static final char BS = 8;
    /** Tab character */
    public static final char TAB = '\t';
    /** Escape character */
    public static final char ESC = 0x1B;

    /**
     * Hidden constructor - can't be instantiated. Accessed only via provided
     * static methods.
     */
    private Console()
    {
    }

    /**
     * Prints one line of text to the constole's standard output. Line is terminated
     * with the new line separator.
     */
    public static synchronized void println(String s)
    {
        print(s);
        print(lineSep);
    }

    /**
     * Prints the text to the console's standard output.
     */
    public static native void print(String s);

    /**
     * Writes single character into standard output
     */
    public static native void putch(char ch);

    /**
     * Reads one character from the console's standard input. If no character is
     * available method returns zero.
     */
    public static native char getKey();

    /**
     * Reads a sequence of characters from the console's standard input. Reading
     * finishes when CR or ESC is pressed. Use Backspace to remove last character 
     * from the input line.
     * @return String that has been read from the console input, or null if ESC
     *         was pressed. CR is not included in the output string.
     */
    public static synchronized String getKeys()
    {
        StringBuffer sb = new StringBuffer();
        while (true)
        {
            if (keyAvail())
            {
                char key = getKey();
                // on escape return null
                if (key == ESC)
                    return null;
                // on CR end reading
                if (key == CR)
                    break;
                // on backspace erase last char
                if (key == BS)
                {
                    if (sb.length() > 0)
                    {
                        sb.setLength(sb.length() - 1);
                        putch(BS);
                        putch(' ');
                        putch(BS);

                    }
                }
                else 
                {
                    sb.append(key);
                    putch(key);
                }
            }
            // relinguish time slice to other threads
            Thread.yield();
        }
        return sb.toString();
    }

    /**
     * Checks if there is character available for reading on the console's
     * standard input.
     */
    public static native boolean keyAvail();
}
